package service

import (
	"blog_server/internal/model/entity"
	"blog_server/internal/model/request"
	"blog_server/internal/model/vo"
	"github.com/jinzhu/gorm"
)

func (svc Service) CreateArticle(param *request.CreateArticleRequest) error {
	article, err := svc.dao.CreateArticle(entity.Article{
		Title:       param.Title,
		Content:     param.Content,
		CategoryId:  param.CategoryId,
		CoverUrl:    param.CoverUrl,
		Quote:       param.Quote,
		Recommended: param.Recommended,
		IsPublic:    param.IsPublic,
	})
	if err != nil {
		return err
	}
	for _, tagID := range param.TagIDList {
		err = svc.dao.CreateTagArticle(tagID, article.ID)
		if err != nil {
			return err
		}
	}
	return err
}

func (svc Service) GetArticleList(page, pageSize int) ([]*vo.ArticleVo, uint, error) {
	cnt, err := svc.dao.CountArticles()
	if err != nil {
		return nil, 0, err
	}
	articles, err := svc.dao.GetAllArticles(page, pageSize)
	if err != nil {
		return nil, 0, err
	}
	var aList []*vo.ArticleVo
	for _, article := range articles {
		aList = append(aList, &vo.ArticleVo{
			ID:          article.ID,
			CreatedAt:   article.CreatedAt.Format("2006-01-02 15:04"),
			UpdatedAt:   article.UpdatedAt.Format("2006-01-02 15:04"),
			Title:       article.Title,
			PageView:    article.PageView,
			CoverUrl:    article.CoverUrl,
			Liked:       article.Liked,
			IsPublic:    article.IsPublic,
			Recommended: article.Recommended,
		})
	}
	return aList, cnt, nil
}

func (svc Service) GetFirstPageArticleList(page, pageSize int) ([]*vo.ArticleVo, error) {
	articles, err := svc.dao.GetFirstArticles(page, pageSize)
	if err != nil {
		return nil, err
	}
	var aList []*vo.ArticleVo
	for _, article := range articles {
		aList = append(aList, &vo.ArticleVo{
			ID:          article.ID,
			CreatedAt:   article.CreatedAt.Format("2006-01-02 15:04"),
			UpdatedAt:   article.UpdatedAt.Format("2006-01-02 15:04"),
			Title:       article.Title,
			PageView:    article.PageView,
			CoverUrl:    article.CoverUrl,
			Liked:       article.Liked,
			IsPublic:    article.IsPublic,
			Recommended: article.Recommended,
		})
	}
	return aList, nil
}

func (svc Service) GetArticleListBySearchText(text string) ([]*vo.ArticleVo, error) {
	articles, err := svc.dao.GetArticleListByText(text)
	if err != nil {
		return nil, err
	}
	var aList []*vo.ArticleVo
	for _, article := range articles {
		aList = append(aList, &vo.ArticleVo{
			ID:          article.ID,
			CreatedAt:   article.CreatedAt.Format("2006-01-02 15:04"),
			UpdatedAt:   article.UpdatedAt.Format("2006-01-02 15:04"),
			Title:       article.Title,
			PageView:    article.PageView,
			CoverUrl:    article.CoverUrl,
			Liked:       article.Liked,
			IsPublic:    article.IsPublic,
			Recommended: article.Recommended,
		})
	}
	return aList, nil
}

func (svc Service) GetArticleByID(id uint) (*vo.ArticlePageVo, error) {
	tagNameList, err := svc.dao.GetTagNameListByArticleID(id)
	if err != nil {
		return nil, err
	}
	article, err := svc.dao.GetArticleByID(id)
	if err != nil {
		return nil, err
	}
	categoryName, err := svc.dao.GetCategoryNameByID(article.CategoryId)
	if err != nil {
		return nil, err
	}
	return &vo.ArticlePageVo{
		ID:        article.ID,
		CreatedAt: article.CreatedAt.Format("2006-01-02 15:04"),
		Title:     article.Title,
		Content:   article.Content,
		PageView:  article.PageView,
		CoverUrl:  article.CoverUrl,
		TagList:   tagNameList,
		Quote:     article.Quote,
		Category:  categoryName,
	}, nil
}

func (svc Service) GetArticleByCategoryID(id uint, page, pageSize int) ([]*vo.ArticleVo, uint, error) {
	cnt, err := svc.dao.CountArticlesByClassID(id)
	if err != nil {
		return nil, 0, err
	}
	articles, err := svc.dao.GetArticlesByCategoryID(id, page, pageSize)
	if err != nil {
		return nil, 0, err
	}
	var aList []*vo.ArticleVo
	for _, article := range articles {
		aList = append(aList, &vo.ArticleVo{
			ID:        article.ID,
			CreatedAt: article.CreatedAt.Format("2006-01-02 15:04"),
			Title:     article.Title,
			PageView:  article.PageView,
			CoverUrl:  article.CoverUrl,
		})
	}
	return aList, cnt, nil
}

func (svc Service) GetEditPageArticleById(id uint) (*request.CreateArticleRequest, error) {
	article, err := svc.dao.GetArticleByID(id)
	if err != nil {
		return nil, err
	}
	tagArticles, err := svc.dao.GetTagArticleByArticleId(id)
	var list []uint
	for _, v := range tagArticles {
		list = append(list, v.TagId)
	}
	return &request.CreateArticleRequest{
		TagIDList:   list,
		Title:       article.Title,
		Content:     article.Content,
		CategoryId:  article.CategoryId,
		CoverUrl:    article.CoverUrl,
		Quote:       article.Quote,
		Recommended: article.Recommended,
		IsPublic:    article.IsPublic,
	}, nil
}

func (svc Service) UpdateArticle(id uint, param request.CreateArticleRequest) error {
	article := entity.Article{
		Model:       &gorm.Model{ID: id},
		Title:       param.Title,
		Content:     param.Content,
		CategoryId:  param.CategoryId,
		CoverUrl:    param.CoverUrl,
		Quote:       param.Quote,
		Recommended: param.Recommended,
		IsPublic:    param.IsPublic,
	}
	return svc.dao.UpdateArticle(id, article, param.TagIDList)
}

func (svc Service) DeleteArticle(id uint) error {
	return svc.dao.DeleteArticle(id)
}
